﻿// -------------------------------------------------------------------------
//    @FileName         :    NFBagPageInterface.h
//    @Author           :    gaoyi
//    @Date             :    2024/12/20
//    @Email            :    445267987@qq.com
//    @Module           :    NFBagPageInterface
//
// -------------------------------------------------------------------------

// --- 文件总结 ---------------------------------------------------------------
// `NFBagPageInterface` 为背包页签的最小接口抽象，供 `NFBagPageOp` 在提交/查询时
// 统一调用，屏蔽具体页签实现细节：
// - 查询：容量、空格子数、是否空、获取物品指针
// - 修改：SetItem 落库、Sort 排序
// - 约束：ItemCanAdd（是否可添加该物品）、GetErrCodeWhenFull（满时错误码）、Equal
// - 生命周期回调：OnCommitBefore/OnCommitAfter
// ---------------------------------------------------------------------------

#pragma once

#include "NFComm/NFCore/NFPlatform.h"

class NFGridItem;
class NFBagPageOp;
class WillAddItemData;

/**
 * @brief 背包页签接口抽象类
 * 为背包页签的最小接口抽象，供 NFBagPageOp 在提交/查询时统一调用
 */
class NFBagPageInterface {
public:
    NFBagPageInterface() { }
    virtual ~NFBagPageInterface() { }
public:
    /**
     * @brief 获取容器容量
     * @param iCapacity 输出容量
     * @return 0成功，非0失败
     */
    virtual int GetCapacity(int& iCapacity) const = 0;
    
    /**
     * @brief 获取空格子数量
     * @param iEmptyGridNum 输出空格子数量
     * @return 0成功，非0失败
     */
    virtual int GetEmptyGridNum(int& iEmptyGridNum) const = 0;
public:
    /**
     * @brief 获取背包页签类型（在同类容器中的索引）
     * @param iIndex 输出页签类型
     * @return 0成功，非0失败
     */
    virtual int GetBagType(int& iIndex) const = 0;
    
    /**
     * @brief 检查指定格子是否为空
     * @param iGridIndex 格子索引
     * @param bIsEmpty 输出是否为空
     * @return 0成功，非0失败
     */
    virtual int GetIsEmpty(int iGridIndex, bool& bIsEmpty) const = 0;
public:
    /**
     * @brief 获取物品指针（不管物品是否空）
     * @param iGridIndex 格子索引
     * @param pItem 输出物品指针（可能返回空指针）
     * @return 0成功，非0失败
     */
    virtual int GetItem(int iGridIndex, NFGridItem*& pItem) const = 0;
    
    /**
     * @brief 设置物品到指定格子（唯一真正改变物品的地方）
     * @param pBagPageOp 背包页签操作器
     * @param iGridIndex 格子索引
     * @param pItem 要设置的物品
     * @param bPreCheckFlag 是否为预检查模式
     * @return 0成功，非0失败
     * @note 内部需要处理当前是否有物品的情况
     */
    virtual int SetItem(const NFBagPageOp* pBagPageOp, int iGridIndex, const NFGridItem* pItem, bool bPreCheckFlag = false) = 0;
    
    /**
     * @brief 是否设置过物品
     * @return true已设置过，false未设置过
     * @note 没有设置过物品，容器的物品就一定没有变动
     */
    virtual bool IsSetWare() const = 0;
    
    /**
     * @brief 判断两个容器是否相等
     * @param pOther 另一个容器接口
     * @return true相等，false不相等
     */
    virtual bool Equal(const NFBagPageInterface* pOther) const = 0;
    
    /**
     * @brief 判断是否可以添加物品
     * @param stWillAddItemData 待添加物品数据
     * @param bCanAdd 输出是否可以添加
     * @return 0成功，非0失败
     */
    virtual int ItemCanAdd(const WillAddItemData& stWillAddItemData, bool& bCanAdd) = 0;
    
    /**
     * @brief 页签已满时，获取添加物品失败的错误码
     * @param iErrCode 输出错误码
     * @return 0成功，非0失败
     */
    virtual int GetErrCodeWhenFull(int& iErrCode) = 0;
public:
    /**
     * @brief 提交前回调
     * @param bPreCheckFlag 是否为预检查模式
     * @return 0成功，非0失败
     */
    virtual int OnCommitBefore(bool bPreCheckFlag = false) = 0;
    
    /**
     * @brief 提交后回调
     * @param pBagPageOp 背包页签操作器
     * @return 0成功，非0失败
     */
    virtual int OnCommitAfter(const NFBagPageOp* pBagPageOp) = 0;
    
    /**
     * @brief 排序物品
     * @return 0成功，非0失败
     */
    virtual int Sort() = 0;
public:
    /**
     * @brief 判断是否为指定角色的物品
     * @param ullRoleID 角色ID
     * @return true是，false否
     */
    virtual bool IsOwner(uint64_t ullRoleID) const = 0;
    
    /**
     * @brief 获取创建时间（毫秒）
     * @return 创建时间戳（毫秒）
     */
    virtual uint64_t GetCreateMS() const { return 0; }
};



